﻿using UnityEngine;

namespace winS.Unity
{
    /// <summary>
    /// 表示一个矩形.
    /// 其左下角为 (0, 0)
    /// </summary>
    public struct RectRange
    {
        /// <summary>
        /// 矩形的大小
        /// </summary>
        public readonly Vector2 size => new Vector2(width, height);
        /// <summary>
        /// 矩形的中心点
        /// </summary>
        public readonly Vector2 center => new Vector2(centerX, centerY);

        /// <summary>
        /// 矩形原点x
        /// </summary>
        public float x { get; private set; }
        /// <summary>
        /// 矩形原点y
        /// </summary>
        public float y { get; private set; }
        /// <summary>
        /// 矩形的宽度
        /// </summary>
        public float width { get; private set; }
        /// <summary>
        /// 矩形的高度
        /// </summary>
        public float height { get; private set; }
        /// <summary>
        /// 矩形中心点x
        /// </summary>
        public float centerX { get; private set; }
        /// <summary>
        /// 矩形中心点y
        /// </summary>
        public float centerY { get; private set; }
        /// <summary>
        /// 矩形的半宽度
        /// </summary>
        public float halfWidth { get; private set; }
        /// <summary>
        /// 矩形的半高度
        /// </summary>
        public float halfHeight { get; private set; }
        /// <summary>
        /// 矩形的最大y
        /// </summary>
        public float up { get; private set; }
        /// <summary>
        /// 矩形的最小x
        /// </summary>
        public float left { get; private set; }
        /// <summary>
        /// 矩形的最大x
        /// </summary>
        public float right { get; private set; }
        /// <summary>
        /// 矩形的最小y
        /// </summary>
        public float bottom { get; private set; }

        /// <summary>
        /// 通过两个点来创建一个矩形范围
        /// </summary>
        /// <param name="bottomLeft">左下点</param>
        /// <param name="upRight">右上点</param>
        public static RectRange CreateRectRangeByTwoPoints(Vector2 bottomLeft, Vector2 upRight)
        {
            return new RectRange(bottomLeft, new Vector2(upRight.x - bottomLeft.x, upRight.y - bottomLeft.y));
        }

        /// <summary>
        /// 创建一个矩形范围
        /// </summary>
        /// <param name="originPoint">矩形的原点</param>
        /// <param name="size">矩形的宽高</param>
        public RectRange(Vector2 originPoint, Vector2 size)
        {
            x = originPoint.x;
            y = originPoint.y;
            width = size.x;
            halfWidth = width * 0.5f;
            height = size.y;
            halfHeight = height * 0.5f;
            left = x;
            right = x + width;
            bottom = y;
            up = y + height;
            centerX = x + halfWidth;
            centerY = y + halfHeight;
        }

        /// <summary>
        /// 是否包含点 <paramref name="point"/>.
        /// 如果当前矩形包含 <paramref name="point"/> 返回 true
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public readonly bool Contains(Vector2 point)
        {
            float x = point.x;
            float y = point.y;
            return !(x < left || x > right || y < bottom || y > up);
        }
        /// <summary>
        /// 是否与 <paramref name="other"/> 重叠.
        /// 如果当前矩形与 <paramref name="other"/> 重叠, 返回 true
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public readonly bool Overlaps(RectRange other)
        {
            return other.right > left && other.left < right && other.up > bottom && other.bottom < up;
        }
        /// <summary>
        /// 如果给定的点超出了矩形范围，则返回在矩形范围内离它最近的点，否则原封不动返回
        /// </summary>
        public readonly bool Restriction(Vector2 point, out Vector2 newPoint)
        {
            bool outRange = false;
            float x = point.x;
            float y = point.y;
            if (x < left)
            {
                x = left;
                outRange = true;
            }
            else if (x > right)
            {
                x = right;
                outRange = true;
            }
            if (y < bottom)
            {
                y = bottom;
                outRange = true;
            }
            else if (y > up)
            {
                y = up;
                outRange = true;
            }
            newPoint.x = x;
            newPoint.y = y;
            return outRange;
        }

        public override readonly string ToString()
        {
            return $"左 {left}, 右 {right}, 上 {up}, 下 {bottom}";
        }
    }
}